package com.dog.basics.service.mtkj.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dog.basics.bean.dto.admin.mtkj.CashWithdrawalEditDto;
import com.dog.basics.bean.dto.admin.mtkj.CashWithdrawalFromDto;
import com.dog.basics.bean.dto.api.mtkj.ApiCashWithdrawalAddDto;
import com.dog.basics.bean.model.common.DogUser;
import com.dog.basics.bean.model.common.DogUserConnect;
import com.dog.basics.bean.model.mtkj.MtCashWithdrawal;
import com.dog.basics.bean.model.mtkj.MtFlowingWater;
import com.dog.basics.bean.model.mtkj.MtShopping;
import com.dog.basics.bean.model.mtkj.MtShoppingAccount;
import com.dog.basics.bean.vo.admin.mtkj.CashWithdrawalVo;
import com.dog.basics.common.constant.CommonConstants;
import com.dog.basics.common.util.HttpContextUtils;
import com.dog.basics.common.util.IpKit;
import com.dog.basics.common.util.PageParam;
import com.dog.basics.common.util.serialNumberUtils;
import com.dog.basics.dao.common.DogUserConnectMapper;
import com.dog.basics.dao.common.DogUserMapper;
import com.dog.basics.dao.mtkj.MtCashWithdrawalMapper;
import com.dog.basics.dao.mtkj.MtFlowingWaterMapper;
import com.dog.basics.dao.mtkj.MtShoppingAccountMapper;
import com.dog.basics.dao.mtkj.MtShoppingMapper;
import com.dog.basics.security.util.SecurityUtils;
import com.dog.basics.service.common.WeChatMiniService;
import com.dog.basics.service.mtkj.IMtCashWithdrawalService;
import com.github.binarywang.wxpay.bean.entpay.EntPayRequest;
import com.github.binarywang.wxpay.bean.entpay.EntPayResult;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 提现记录 服务实现类
 * </p>
 *
 * @author wph
 * @since 2020-11-09
 */
@Service
@AllArgsConstructor
public class MtCashWithdrawalServiceImpl extends ServiceImpl<MtCashWithdrawalMapper, MtCashWithdrawal> implements IMtCashWithdrawalService {
    private final MtShoppingMapper mtShoppingMapper;
    private final MtShoppingAccountMapper mtShoppingAccountMapper;
    private final MtFlowingWaterMapper mtFlowingWaterMapper;
    private final DogUserMapper dogUserMapper;
    private final WeChatMiniService weChatMiniService;
    private final DogUserConnectMapper dogUserConnectMapper;


    /**
     * 分页的条件公用类
     *
     * @param name,mobile
     * @param shopIds
     */
    public List<Long> getshopIdsWhere(String name, List<Long> shopIds) {
        List<Long> collect = mtShoppingMapper.selectList(Wrappers.<MtShopping>lambdaQuery().like(StrUtil.isNotBlank(name), MtShopping::getName, name)).stream().map(e -> e.getId()).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(collect)) {
            shopIds = collect;
        } else {
            shopIds.add(-2L);
        }
        return shopIds;
    }

    /**
     * @Description: 分页提现记录
     * @Param: status
     * @return: IPage<HospitalVo>
     * @Author: wph
     * @Date:
     */
    @Override
    public IPage<CashWithdrawalVo> getPageList(PageParam page, CashWithdrawalFromDto obj) {
        // 判断店铺ID
        List<Long> shopIds = CollUtil.newArrayList();
        if (StrUtil.isNotBlank(obj.getShopName())) {
            shopIds = getshopIdsWhere(obj.getShopName(), shopIds);
        }

        IPage iPage = this.page(page, Wrappers.<MtCashWithdrawal>lambdaQuery()
                .in(CollUtil.isNotEmpty(shopIds), MtCashWithdrawal::getShopId, shopIds)
                .like(StrUtil.isNotBlank(obj.getAccountNumber()), MtCashWithdrawal::getAccountNumber, obj.getAccountNumber())
                .like(StrUtil.isNotBlank(obj.getSerialNo()), MtCashWithdrawal::getSerialNo, obj.getSerialNo())
                .like(StrUtil.isNotBlank(obj.getBankName()), MtCashWithdrawal::getBankName, obj.getBankName())
                .like(StrUtil.isNotBlank(obj.getRealName()), MtCashWithdrawal::getRealName, obj.getRealName())
                .eq(ObjectUtil.isNotNull(obj.getAccountType()), MtCashWithdrawal::getAccountType, obj.getAccountType())
                .eq(ObjectUtil.isNotNull(obj.getAuditStatus()), MtCashWithdrawal::getAuditStatus, obj.getAuditStatus())
                .orderBy(Boolean.TRUE, obj.getIsOrderByAvg(), MtCashWithdrawal::getCreateTime));
        List<MtCashWithdrawal> records = iPage.getRecords();
        iPage.setRecords(records.stream().map(e -> {
            CashWithdrawalVo newsVo = BeanUtil.copyProperties(e, CashWithdrawalVo.class);
            //查询
            MtShopping mtShopping = mtShoppingMapper.selectById(e.getShopId());
            newsVo.setShopName(ObjectUtil.isNotNull(mtShopping) ? mtShopping.getName() : "");
            return newsVo;
        }).collect(Collectors.toList()));
        return iPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @SneakyThrows
    public Boolean saveObj(ApiCashWithdrawalAddDto obj) {
        //获取当前用户的店铺ID
        List<MtShopping> shopList = mtShoppingMapper.selectList(Wrappers.<MtShopping>lambdaQuery().eq(MtShopping::getStatus, 1).eq(MtShopping::getUserId, SecurityUtils.getUser().getUserId()).orderByDesc(MtShopping::getCreateTime));
        Validator.validateTrue(CollUtil.isNotEmpty(shopList), "该用户还不是商家");
        DogUser user = dogUserMapper.selectById(SecurityUtils.getUser().getUserId());
        Validator.validateNotNull(user, "用户不存在");
        Validator.validateEqual(user.getPayPassword(), obj.getPayPassword(), "提现密码不正确!");
        MtCashWithdrawal mtCashWithdrawal = new MtCashWithdrawal();
        BeanUtil.copyProperties(obj, mtCashWithdrawal);
        mtCashWithdrawal.setSerialNo(serialNumberUtils.serialNumberGenerate().toString());
        mtCashWithdrawal.setCreateTime(DateUtil.currentSeconds());
        mtCashWithdrawal.setShopId(shopList.get(0).getId());
        mtCashWithdrawal.setUserId(SecurityUtils.getUser().getUserId());
        mtCashWithdrawal.setCreateBy(SecurityUtils.getUser().getUserId());
        Validator.validateTrue(this.save(mtCashWithdrawal), "增加数据失败!");
        //查询店铺账号
        List<MtShoppingAccount> list1 = mtShoppingAccountMapper.selectList(Wrappers.<MtShoppingAccount>lambdaQuery().eq(MtShoppingAccount::getShopId, mtCashWithdrawal.getShopId()).orderByDesc(MtShoppingAccount::getCreateTime));
        Validator.validateTrue(CollUtil.isNotEmpty(list1), "店铺信息不完善");
        //开始流水
        MtShoppingAccount mtShoppingAccount = list1.get(0);
        mtShoppingAccount.setMoney(mtShoppingAccount.getMoney().subtract(mtCashWithdrawal.getMoney()));
        mtShoppingAccount.setUpdateTime(DateUtil.currentSeconds());
        Validator.validateTrue(retBool(mtShoppingAccountMapper.updateById(mtShoppingAccount)), "店铺余额操作失败!");
        return Boolean.TRUE;
    }
    /**
     * @Description: 审核提现记录
     * @Param: ApiBankAccountAddDto
     * @return: Boolean
     * @Author: wph
     * @Date: 2020/05/29  0027
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editObj(CashWithdrawalEditDto obj) {
        MtCashWithdrawal dogNews = this.getById(obj.getId());
        Validator.validateNotNull(dogNews, "无此数据!");
        Validator.validateEqual(dogNews.getAuditStatus(), 0, "只有待审核才能操作!");
        //查询店铺账号
        List<MtShoppingAccount> list1 = mtShoppingAccountMapper.selectList(Wrappers.<MtShoppingAccount>lambdaQuery().eq(MtShoppingAccount::getShopId, dogNews.getShopId()).orderByDesc(MtShoppingAccount::getCreateTime));
        Validator.validateTrue(CollUtil.isNotEmpty(list1), "店铺信息不完善");
        if (obj.getAuditStatus() == 1) {
            //开始流水
            MtShoppingAccount mtShoppingAccount = list1.get(0);
            mtShoppingAccount.setMoney(mtShoppingAccount.getMoney().add(dogNews.getMoney()));
            mtShoppingAccount.setUpdateTime(DateUtil.currentSeconds());
            Validator.validateTrue(retBool(mtShoppingAccountMapper.updateById(mtShoppingAccount)), "店铺增加余额失败!");
        } else if (obj.getAuditStatus() == 2) {
            MtFlowingWater mtFlowingWater1 = new MtFlowingWater();
            mtFlowingWater1.setSerialNo(dogNews.getSerialNo());
            mtFlowingWater1.setWaterUserId(dogNews.getUserId());
            mtFlowingWater1.setWaterShopId(dogNews.getShopId());
            mtFlowingWater1.setWaterMoney(dogNews.getMoney().negate());
            mtFlowingWater1.setWaterType(1);
            mtFlowingWater1.setWaterAccount(3);
            mtFlowingWater1.setInoutType(2);
            mtFlowingWater1.setWaterExplain("提现");
            mtFlowingWater1.setCreateTime(DateUtil.currentSeconds());
            mtFlowingWater1.setCreateBy(dogNews.getUserId());
            Validator.validateTrue(retBool(mtFlowingWaterMapper.insert(mtFlowingWater1)), "用户流水增加失败!");
        }
        dogNews.setAuditStatus(obj.getAuditStatus());
        Validator.validateTrue(this.updateById(dogNews), "增加数据失败!");
        return Boolean.TRUE;
    }
    /**
     * @Description: 审核提现记录
     * @Param: ApiBankAccountAddDto
     * @return: Boolean
     * @Author: wph
     * @Date: 2020/05/29  0027
     */
    public Boolean editObj1(CashWithdrawalEditDto obj) {
        MtCashWithdrawal dogNews = this.getById(obj.getId());
        Validator.validateNotNull(dogNews, "无此数据!");
        Validator.validateEqual(dogNews.getAuditStatus(), 0, "只有待审核才能操作!");
        //查询店铺账号
        List<MtShoppingAccount> list1 = mtShoppingAccountMapper.selectList(Wrappers.<MtShoppingAccount>lambdaQuery().eq(MtShoppingAccount::getShopId, dogNews.getShopId()).orderByDesc(MtShoppingAccount::getCreateTime));
        Validator.validateTrue(CollUtil.isNotEmpty(list1), "店铺信息不完善");
        MtShoppingAccount mtShoppingAccount = list1.get(0);
        if (obj.getAuditStatus() == 1) {
            //开始流水
            mtShoppingAccount.setMoney(mtShoppingAccount.getMoney().add(dogNews.getMoney()));
            mtShoppingAccount.setUpdateTime(DateUtil.currentSeconds());
            Validator.validateTrue(retBool(mtShoppingAccountMapper.updateById(mtShoppingAccount)), "店铺增加余额失败!");
        } else if (obj.getAuditStatus() == 2) {
            List<DogUserConnect> list = dogUserConnectMapper.selectList(Wrappers.<DogUserConnect>lambdaQuery().eq(DogUserConnect::getUserId, dogNews.getUserId()));
            if (CollUtil.isNotEmpty(list)) {
                DogUserConnect dogUserConnect = list.get(0);
                if(StrUtil.isNotBlank(dogUserConnect.getMiniShopOpenid())){
                    DogUser dogUser = dogUserMapper.selectById(dogUserConnect.getUserId());
                    // 判断微信
                    EntPayRequest request =
                            EntPayRequest.newBuilder()
                                    .partnerTradeNo(dogNews.getSerialNo())
                                    .openid(dogUserConnect.getMiniShopOpenid())
                                    .checkName("NO_CHECK")
                                    .reUserName(ObjectUtil.isNotNull(dogUser)?dogUser.getNickName():"")
                                    .amount(dogNews.getMoney().multiply(BigDecimal.valueOf(100)).intValue())
                                    .description("提现收益金额")
                                    .spbillCreateIp(IpKit.getRealIp(HttpContextUtils.getHttpServletRequest()))
                                    .build();
                    EntPayResult entPayResult = weChatMiniService.wxEntPay(request);
                    if (Validator.equal(entPayResult.getReturnCode(), CommonConstants.STR_SUCCESS) && Validator.equal(entPayResult.getResultCode(), CommonConstants.STR_SUCCESS)) {
                        MtFlowingWater mtFlowingWater1 = new MtFlowingWater();
                        mtFlowingWater1.setSerialNo(dogNews.getSerialNo());
                        mtFlowingWater1.setWaterUserId(dogNews.getUserId());
                        mtFlowingWater1.setWaterShopId(dogNews.getShopId());
                        mtFlowingWater1.setWaterMoney(dogNews.getMoney().negate());
                        mtFlowingWater1.setWaterType(1);
                        mtFlowingWater1.setWaterAccount(3);
                        mtFlowingWater1.setInoutType(2);
                        mtFlowingWater1.setWaterExplain("提现");
                        mtFlowingWater1.setCreateTime(DateUtil.currentSeconds());
                        mtFlowingWater1.setCreateBy(dogNews.getUserId());
                        Validator.validateTrue(retBool(mtFlowingWaterMapper.insert(mtFlowingWater1)), "用户流水增加失败!");
                    }else{
                        Validator.validateTrue(false, "微信退款失败");
                    }
                }


            }

        }
        dogNews.setAuditStatus(obj.getAuditStatus());
        Validator.validateTrue(this.updateById(dogNews), "增加数据失败!");
        return Boolean.TRUE;
    }
}
